﻿//-------------------------------------------------------------------
//	Copyright (c) 2010-2014  Zhirnov Andrey
//	This file is part of the "UX Standard Lib" project.
//	See copyright notice in "UX_STL_Core.h".
//-------------------------------------------------------------------

#ifndef _UXS_ALL_FUNC_FORWARD_DECL_H
#define _UXS_ALL_FUNC_FORWARD_DECL_H

#pragma once

#include "Types.h"
#include "../Math/MathFunc.h"

namespace UX_STL
{
namespace UXTypes
{

	//
	// Type Info
	//
	
	namespace TypeTraits {}
	namespace TypeDescriptor {}

	template <typename T>				struct TypeInfo;

	template <typename T>				inline T		MinValue (const T& v = T());
	template <typename T>				inline T		MaxValue (const T& v = T());
	template <typename T>				inline bool		CheckValue (const T& val);
	template <typename T>				inline T		Infinity ();
	template <typename T>				inline T		NaN ();

	template <typename T>				inline bool		IsNaN (const T& x);
	template <typename T>				inline bool		IsInfinity (const T& x);
	template <typename T>				inline bool		IsFinite (const T& x);



	//
	// Type Cast
	//

	template <typename R, typename T>	inline const R & ReferenceCast (const T & t);
	template <typename R, typename T>	inline R & ReferenceCast (T & t);

	template <typename R, typename T>	inline R LimitClampCast (const T &t);
	template <typename R, typename T>	inline R LimitCheckCast (const T &t);



	//
	// Converters
	//

	template <typename T>				inline uint		GetMaxBitNumber (T value);
	template <typename T>				inline uint		GetNumberOfBits (T value);
	
	template <typename T>				inline T *		AddressOf (T &tValue);
	template <typename T>				inline const T * const AddressOf (const T &tValue);
	
	template <typename T, usize I>		inline usize	CountOf (const T (&arr)[I]);



	//
	// Enum Compare functions
	//
	
	template <typename T1, typename T2>
	inline bool	 EnumCmp (const T1& flags, const T2& flag);

	template <typename T1, typename T2, typename T3>
	inline bool  EnumCmp (const T1& flags, const T2& mask, const T3& flag);
	
	template <typename T1, typename T2>
	inline bool  EnumCmpE (const T1& flags, const T2& flag);
	
	template <typename T1, typename T2, typename T3>
	inline bool  EnumCmpX (const T1& flags1, const T2& flags2, const T3& mask);
	
	template <typename T1, typename T2>
	inline bool  EnumNoCmp (const T1& flags, const T2& flag);
	
	template <typename T1, typename T2>
	inline bool  EnumNoCmpE (const T1& flags, const T2& flag);



	//
	// Memory Allocation/Deallocation
	//
	
	inline void *	_alloc(usize size);
	inline void		_dealloc(void *&ptr);

	inline void *	_aligned_alloc(usize size, uint align);
	inline void		_aligned_dealloc(void *&ptr);



	//
	// Pointer Operations
	//
	
	template <typename T, typename B>		inline isize	PointerOffset(const T *pleft, const B *pright);
	template <typename B>					inline isize	ClassFieldOffset(B field);
	template <typename T, typename B>		inline isize	ClassOffsetOfBase();



	//
	// Memory Operations
	//
	
	template <typename T>
	inline bool Memmove2D(T *pMem, usize uWidth, usize uHeight, isize idX, isize idY);
	inline bool Memmove2D(void *pMem, const usize uElemSize, usize uWidth, usize uHeight, isize idX, isize idY);
	
	template <typename T>
	inline bool Memcpy2D(T *pDst, const T *pSrc, usize uDstWidth, usize uDstHeigth,
						 usize uSrcWidth, usize uSrcHeight, usize uDstOffsetX, usize uDstOffsetY);
	inline bool Memcpy2D(void *pDst, const void *pSrc, const usize uElemSize, usize uDstWidth, usize uDstHeight,
						 usize uSrcWidth, usize uSrcHeight, usize uDstOffsetX, usize uDstOffsetY);
	
	template <typename T>
	inline void Memcpy2DRotate90rev(T *pDst, const T *pSrc, usize uWidth, usize uHeight);
	inline void Memcpy2DRotate90rev(void *pDst, const void *pSrc, usize uWidth, usize uHeight, const usize uElemSize);
	
	template <typename T>
	inline void Memcpy2DRotate90(T *pDst, const T *pSrc, usize uWidth, usize uHeight);
	inline void Memcpy2DRotate90(void *pDst, const void *pSrc, usize uWidth, usize uHeight, const usize uElemSize);
	
	template <typename T>
	inline void Memcpy2DRotate180(T *pDst, const T *pSrc, usize uWidth, usize uHeight);
	inline void Memcpy2DRotate180(void *pDst, const void *pSrc, usize uWidth, usize uHeight, const usize uElemSize);
	
	template <typename T>
	inline bool Memset2D(T *pBase, usize uWidth, usize uHeight, usize uOffsetX, usize uOffsetY, usize uSizeX, usize uSizeY, const T &tValue);
	
	template <typename T>
	inline void Memset2D(T *pBase, usize uWidth, usize uHeight, const T &tValue);


	template <typename T, typename B>			inline T *	MemSet(T *pBase, usize uCount, const B &tValue);
	template <typename T, typename B>			inline T *	MemSet(T *pBase, T *pEnd, const B &tValue);
	template <typename T, typename B, usize I>	inline T *	MemSet(T (&tArr)[I], const B &tValue);
	
	template <typename T>						inline T *	MemSetDefault(T *pBase, usize uCount);
	template <typename T>						inline T *	MemSetDefault(T *pBase, T *pEnd);
	template <typename T, usize I>				inline T *	MemSetDefault(T (&tArr)[I]);
	
	template <typename T, usize I>				inline T * ZeroMem(T (&tArr)[I]);
	template <typename T>						inline T & ZeroMem(T &val);
												inline void * ZeroMem(void *pDst, usize uSize);


//-------------------------------------------------------------------
	
}	// UXTypes
}	// UX_STL

#endif	// _UXS_ALL_FUNC_FORWARD_DECL_H